# -*- coding: utf-8 -*-
"""
云存储适配器基类
@api-version: 1.0.0
// REF: API-NETDISK-007
"""

from abc import ABC, abstractmethod
from typing import Optional, Dict, Any, BinaryIO
from datetime import datetime, timedelta

class CloudStorageAdapter(ABC):
    """云存储适配器基类
    
    定义统一的云存储操作接口，支持多种云存储服务的扩展
    所有云存储适配器都必须继承此类并实现抽象方法
    """
    
    def __init__(self, **config):
        """初始化云存储适配器
        
        Args:
            **config: 配置参数，具体参数由子类定义
        """
        self.config = config
        self.provider_name = self.__class__.__name__.replace('Adapter', '').lower()
    
    @abstractmethod
    def upload_file(self, file_stream: BinaryIO, file_name: str, 
                   file_size: int, content_type: str = None) -> Dict[str, Any]:
        """上传文件到云存储
        
        Args:
            file_stream: 文件流
            file_name: 文件名
            file_size: 文件大小（字节）
            content_type: 文件MIME类型
        
        Returns:
            Dict: 上传结果
            {
                'success': bool,           # 是否成功
                'cloud_file_id': str,      # 云端文件ID
                'download_url': str,       # 下载链接
                'expires_at': datetime,    # 链接过期时间
                'file_size': int,          # 实际文件大小
                'error_message': str       # 错误信息（失败时）
            }
        """
        pass
    
    @abstractmethod
    def get_download_url(self, cloud_file_id: str, expires_in: int = 3600) -> Dict[str, Any]:
        """获取文件下载链接
        
        Args:
            cloud_file_id: 云端文件ID
            expires_in: 链接有效期（秒），默认1小时
        
        Returns:
            Dict: 下载链接信息
            {
                'success': bool,           # 是否成功
                'download_url': str,       # 下载链接
                'expires_at': datetime,    # 过期时间
                'error_message': str       # 错误信息（失败时）
            }
        """
        pass
    
    @abstractmethod
    def delete_file(self, cloud_file_id: str) -> Dict[str, Any]:
        """删除云端文件
        
        Args:
            cloud_file_id: 云端文件ID
        
        Returns:
            Dict: 删除结果
            {
                'success': bool,           # 是否成功
                'error_message': str       # 错误信息（失败时）
            }
        """
        pass
    
    @abstractmethod
    def get_file_info(self, cloud_file_id: str) -> Dict[str, Any]:
        """获取文件信息
        
        Args:
            cloud_file_id: 云端文件ID
        
        Returns:
            Dict: 文件信息
            {
                'success': bool,           # 是否成功
                'file_id': str,            # 文件ID
                'file_name': str,          # 文件名
                'file_size': int,          # 文件大小
                'content_type': str,       # 文件类型
                'created_at': datetime,    # 创建时间
                'modified_at': datetime,   # 修改时间
                'error_message': str       # 错误信息（失败时）
            }
        """
        pass
    
    def check_file_exists(self, cloud_file_id: str) -> bool:
        """检查文件是否存在
        
        Args:
            cloud_file_id: 云端文件ID
        
        Returns:
            bool: 文件是否存在
        """
        result = self.get_file_info(cloud_file_id)
        return result.get('success', False)
    
    def get_storage_quota(self) -> Dict[str, Any]:
        """获取存储配额信息（可选实现）
        
        Returns:
            Dict: 配额信息
            {
                'success': bool,           # 是否成功
                'total_space': int,        # 总空间（字节）
                'used_space': int,         # 已用空间（字节）
                'available_space': int,    # 可用空间（字节）
                'error_message': str       # 错误信息（失败时）
            }
        """
        return {
            'success': False,
            'error_message': 'Storage quota not supported by this provider'
        }
    
    def generate_upload_token(self, file_name: str, file_size: int) -> Dict[str, Any]:
        """生成上传令牌（可选实现，用于客户端直传）
        
        Args:
            file_name: 文件名
            file_size: 文件大小
        
        Returns:
            Dict: 上传令牌信息
            {
                'success': bool,           # 是否成功
                'upload_token': str,       # 上传令牌
                'upload_url': str,         # 上传地址
                'expires_at': datetime,    # 令牌过期时间
                'error_message': str       # 错误信息（失败时）
            }
        """
        return {
            'success': False,
            'error_message': 'Direct upload not supported by this provider'
        }
    
    def batch_delete_files(self, cloud_file_ids: list) -> Dict[str, Any]:
        """批量删除文件（可选实现）
        
        Args:
            cloud_file_ids: 云端文件ID列表
        
        Returns:
            Dict: 批量删除结果
            {
                'success': bool,           # 是否成功
                'deleted_count': int,      # 成功删除数量
                'failed_files': list,      # 删除失败的文件ID
                'error_message': str       # 错误信息（失败时）
            }
        """
        # 默认实现：逐个删除
        deleted_count = 0
        failed_files = []
        
        for file_id in cloud_file_ids:
            result = self.delete_file(file_id)
            if result.get('success', False):
                deleted_count += 1
            else:
                failed_files.append({
                    'file_id': file_id,
                    'error': result.get('error_message', 'Unknown error')
                })
        
        return {
            'success': len(failed_files) == 0,
            'deleted_count': deleted_count,
            'failed_files': failed_files,
            'error_message': f'{len(failed_files)} files failed to delete' if failed_files else None
        }
    
    def test_connection(self) -> Dict[str, Any]:
        """测试连接（可选实现）
        
        Returns:
            Dict: 连接测试结果
            {
                'success': bool,           # 是否成功
                'response_time': float,    # 响应时间（秒）
                'error_message': str       # 错误信息（失败时）
            }
        """
        return {
            'success': False,
            'error_message': 'Connection test not implemented'
        }
    
    def get_provider_info(self) -> Dict[str, Any]:
        """获取提供商信息
        
        Returns:
            Dict: 提供商信息
        """
        return {
            'provider_name': self.provider_name,
            'adapter_class': self.__class__.__name__,
            'supported_features': self.get_supported_features()
        }
    
    def get_supported_features(self) -> Dict[str, bool]:
        """获取支持的功能列表
        
        Returns:
            Dict: 功能支持情况
        """
        return {
            'upload': True,
            'download': True,
            'delete': True,
            'file_info': True,
            'batch_delete': hasattr(self, 'batch_delete_files'),
            'direct_upload': hasattr(self, 'generate_upload_token'),
            'storage_quota': hasattr(self, 'get_storage_quota'),
            'connection_test': hasattr(self, 'test_connection')
        }
    
    def _format_error_response(self, error_message: str, **kwargs) -> Dict[str, Any]:
        """格式化错误响应
        
        Args:
            error_message: 错误信息
            **kwargs: 其他参数
        
        Returns:
            Dict: 错误响应
        """
        response = {
            'success': False,
            'error_message': error_message
        }
        response.update(kwargs)
        return response
    
    def _format_success_response(self, **kwargs) -> Dict[str, Any]:
        """格式化成功响应
        
        Args:
            **kwargs: 响应数据
        
        Returns:
            Dict: 成功响应
        """
        response = {'success': True}
        response.update(kwargs)
        return response
    
    def _calculate_expires_at(self, expires_in: int) -> datetime:
        """计算过期时间
        
        Args:
            expires_in: 有效期（秒）
        
        Returns:
            datetime: 过期时间
        """
        return datetime.utcnow() + timedelta(seconds=expires_in)
    
    def __str__(self):
        return f"{self.__class__.__name__}({self.provider_name})"
    
    def __repr__(self):
        return f"<{self.__class__.__name__} provider='{self.provider_name}'>"